using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using tutFuelCellGame.Sprites;

namespace tutFuelCellGame
{
    public class Hud
    {
        private readonly Texture2D texBackground;
        private TimerBar timerBar;
        private FuelCellsIndicator fuelCellsIndicator;

        public Hud(Texture2D texFuelCells, Texture2D texBackground, Texture2D texTimerBar, AnimationManager animationManager)
        {
            this.texBackground = texBackground;

            timerBar = new TimerBar(texTimerBar);
            fuelCellsIndicator = new FuelCellsIndicator(texFuelCells, animationManager);
        }

        public Rectangle TimeRemainingIndicatorArea
        {
            get { return timerBar.DrawingArea; }
            set { timerBar.DrawingArea = value; }
        }

        public Rectangle FuelCellsIndicatorArea
        {
            get { return fuelCellsIndicator.DrawingArea; }
            set
            {
                fuelCellsIndicator.DrawingArea = value;
            }
        }

        public void SetTimeLeft(float secondsLeft)
        {
            timerBar.SetSecondsLeft(secondsLeft);
        }

        public void Initialize(LevelInformation info)
        {
            timerBar.Initialize(info.RoundTimeInSeconds);
            fuelCellsIndicator.Initialize(info);
        }

        public void OnCanisterFound(int numOfRetrievedCanisters)
        {
            fuelCellsIndicator.OnCanisterFound(numOfRetrievedCanisters);
        }

        public void Draw (SpriteBatch batch)
        {
            Rectangle bkgd = Rectangle.Union(FuelCellsIndicatorArea, TimeRemainingIndicatorArea);
            bkgd.Inflate(10, 10);
            batch.Draw(texBackground, bkgd, Color.White);

            fuelCellsIndicator.Draw(batch);
            timerBar.Draw(batch);
        }
    }

    public class FuelCellsIndicator: Sprite
    {
        private readonly AnimationManager animationManager;
        private Rectangle drawingArea;
        private Rectangle shadowArea;
        private List<Sprite> _sprites;

        public FuelCellsIndicator(Texture2D texture, AnimationManager animationManager) : base(texture)
        {
            this.animationManager = animationManager;
        }

        public Rectangle DrawingArea
        {
            get { return drawingArea; }
            set
            {
                drawingArea = value;
                shadowArea = drawingArea;
                shadowArea.Inflate(+5, +5);
            }
        }

        public void Initialize(LevelInformation info)
        {
            _sprites = new List<Sprite>(info.NumOfFuelCells);
            float totalWidthNeeded = (info.NumOfFuelCells + 1) * (Texture.Width);
            float totalWidthAvailable = DrawingArea.Width;
            float scale = totalWidthAvailable / totalWidthNeeded;

            float totalHeightNeeded = Texture.Height;
            float totalHeightAvailable = DrawingArea.Height;
            float scaleHeight = totalHeightAvailable / totalHeightNeeded;

            if (scaleHeight < scale) scale = scaleHeight;
            float spacingX = totalWidthAvailable - (info.NumOfFuelCells * Texture.Width * scale);
            for (int i = 0; i < info.NumOfFuelCells; i++)
            {
                var sprite = new Sprite(Texture)
                {
                    Scale = scale,
                    Opacity = 0.4f
                };
                sprite.Center = new Vector2(DrawingArea.X + (i + 1) * spacingX,
                                              DrawingArea.Top + DrawingArea.Height / 2);
                _sprites.Add(sprite);
            }
            
        }

        public void OnCanisterFound(int numOfRetrievedCanisters)
        {
            if (numOfRetrievedCanisters <= 0) return;
            var sprite = _sprites[numOfRetrievedCanisters - 1];
            animationManager.StartHUDFuelCellAnimation(sprite);

        }

        public override void Draw(SpriteBatch batch)
        {
            foreach (var sprite in _sprites)
            {
                sprite.Draw(batch);
            }
        }
    }

    public class TimerBar: Sprite
    {
        private float progress;
        private float totalSeconds;
        private Rectangle drawingArea;

        public TimerBar(Texture2D texture) : base(texture)
        {
            
        }

        public Rectangle DrawingArea
        {
            get { return drawingArea; }
            set { drawingArea = value; }
        }

        public void Initialize(int duration)
        {
            totalSeconds = duration;
            progress = 0;
        }

        /// <summary>
        /// should be called from Game.Update 
        /// </summary>
        /// <param name="secondsLeft"></param>
        public void SetSecondsLeft(float secondsLeft)
        {
            progress = (totalSeconds - secondsLeft) / totalSeconds;
        }

        public override void Draw(SpriteBatch batch)
        {
            //Draw the negative space for the health bar
            batch.Draw(Texture, DrawingArea, new Rectangle(0, 90, Texture.Width, 44), Color.White);

            //Draw the current health level based on the current Health
            batch.Draw(Texture, new Rectangle(DrawingArea.X, drawingArea.Y, (int)(drawingArea.Width - drawingArea.Width * progress), drawingArea.Height),
                 new Rectangle(0, 45, Texture.Width, 44), Color.DarkGoldenrod);

            //Draw the box around the health bar
            batch.Draw(Texture, drawingArea, new Rectangle(0, 0, Texture.Width, 44), Color.White);
        }
    }
}